#include <iostream>
#include <functional>

using namespace std;

class Add
{
public:
    int operator()(int a, int b)
    {
        return a + b;
    }
};

int add(int a, int b)
{
    return a + b;
}

// void test(int a, int b,int (*func)(int, int))
// {
//     cout << "add = " << func(a,b) << endl;
// }

void test(int a, int b, const function<int(int,int)> &func)
{
    cout << "add = " << func(a,b) << endl;
}

int main(int argc, char **argv)
{
    auto p_add = [](int a, int b){return a + b;};

    using P_FUNC = int(*)(int,int);
    P_FUNC p_func = add;

    Add a;

    cout << add(5,6) << endl;
    cout << a(5,6) << endl;
    cout << p_func(5,6) << endl;
    cout << p_add(5,6) << endl;


    test(5,6,add); // test(5,6, function<int(int,int)>(add));
    test(5,6,p_func);
    test(5,6,a);
    test(5,6,p_add);
     
    function<int(int, int)> f1(add);
    function<int(int, int)> f2(p_func);
    function<int(int, int)> f3(a);
    function<int(int, int)> f4(p_add); 

    cout << f1(5,6) << endl;
    cout << f2(5,6) << endl;
    cout << f3(5,6) << endl;;
    cout << f4(5,6) << endl;





    
    return 0;
}